package networkSimulation.simulation.social.simulation

import networkSimulation.simulation.social.framework.{Friendship, Person}
import networkSimulation.simulator.Simulator
import networkSimulation.visualisation.graph.graphviz.GraphvizVisualiser
import networkSimulation.statistic.StatisticsManager
import networkSimulation.statistic.basicStatistics.EdgeXY
import networkSimulation.simulation.social.statistic.{AmountIncreasedFriendshipBar, PercentageIncreased, AmountsFriendshipPie, AmountsFriendshipLine}
import networkSimulation.simulation.virus.InfectablePerson
import networkSimulation.framework.{Edge, Node, Graph}

/**
 * Social simulation.
 *
 * @author  Tim Caljé
 *          Jeroen De Raedt
 *          Jorick Van Aken
 */
class SocialGraph(graph: Graph[Person,Friendship[Person]]) extends Simulator[Person,Friendship[Person]](graph) with GraphvizVisualiser[Person,Friendship[Person]]{

   /**
   * Variable holding the path for the visual representations
   */
  private var outputPath = ""

  /**
   *  Provide statistics-support by adding a statisticsManager to this simulation.
   */
  private var statisticsManager = new StatisticsManager[Person,Friendship[Person]]()

  /**
   * Add statistics to the statisticsManager
   */
  statisticsManager.addStatistic(new EdgeXY[Person,Friendship[Person]]())
  statisticsManager.addStatistic(new AmountsFriendshipLine[Person,Friendship[Person]]())
  statisticsManager.addStatistic(new AmountsFriendshipPie[Person,Friendship[Person]]())
  statisticsManager.addStatistic(new PercentageIncreased[Person,Friendship[Person]]())
  statisticsManager.addStatistic(new AmountIncreasedFriendshipBar[Person,Friendship[Person]]())
  /**
   *  Start the simulation.
   *
   * @param turns
   *        The number of turns that the simulation will go through
   * @param path
   *        The path were all (temporary) files will be saved
   * @post The outputPath will be set
   *        | this.outputPath = path
   * @post A snapshot of the initial graph will be made
   *        | super.saveVisualGraph(outputPath)
   * @post The simulation will run 'turns' times
   *        | for 0 to turns do
   *        |   run()
   *        | end for
   */
  def startSimulation( turns : Int, path : String){
    this.outputPath = path
    clean(this.outputPath)
    super.saveVisualGraph(outputPath)
    for (i <- 0 until turns)
      run()
    statisticsManager.generateStatistics(outputPath);
  }

  /**
   * Run the simulation.
   *
   * @post  The simulation method of each node will be called
   *        | super.run()
   */
  @Override
  override def run(){
    super.run()
    super.saveVisualGraph(this.outputPath)
    statisticsManager.updateStatistics(outputPath,graph)
    super.publish()
  }

}